/* 
 * File:   QR.h
 * Author: gustavo
 *
 * Created on August 21, 2012, 2:03 AM
 */

#ifndef QR_HPP
#define	QR_HPP

#include "QRInterface.hpp"

#include "../matrix.hpp"


namespace imp {

	namespace math {

		template <typename T, class Algorithm> class QR : public QRInterface< T > {
			/////

		public:
			Matrix<T> H;
			Matrix<T> Qt;
			Matrix<T> R;

			T * hh_half_dot;
			T * Rdiag;


		public: /* Constructors */
			template <typename Tin> QR(Matrix<Tin> & orig);
			virtual ~QR();

		public: /* Implements QRInterface<T> */
			const Matrix<T>& getR() const;
			const Matrix<T>& getQt() const;
			const Matrix<T>& getHouseHolderVectors() const;

			bool isSingular() const;
			T determinant() const;
			Matrix<T> solve(Matrix<T>& B) const;

		public: /* Implements DecomposeInterface */
			bool modifiedInput() const;
		private:
			void decompose(Matrix<T>& M);

		};

		/* = Constructors ======================================================= */
		template <typename T, class Algorithm> template <typename Tin> QR<T, Algorithm>::QR(Matrix<Tin>& orig) {

			H.copy(orig);
			Qt.setSize(H.rows, H.rows);
			R.setSize(H.rows, H.columns);

			this->decompose(H);
		}

		template <typename T, class Algorithm> QR<T, Algorithm>::~QR() {

		}

		/* = Implements QR Interface ============================================ */

		template <typename T, class Algorithm> const Matrix<T>& QR<T, Algorithm>::getQt() const {
			return Qt;
		}

		template <typename T, class Algorithm> const Matrix<T>& QR<T, Algorithm>::getR() const {
			return this->R;
		}

		template <typename T, class Algorithm> const Matrix<T>& QR<T, Algorithm>::getHouseHolderVectors() const {
			return this->H;
		}

		template <typename T, class Algorithm> T QR<T, Algorithm>::determinant() const {

		}

		template <typename T, class Algorithm> bool QR<T, Algorithm>::isSingular() const {

		}

		template <typename T, class Algorithm> Matrix<T> QR<T, Algorithm>::solve(Matrix<T>& B) const {

		}


	}
}


#endif	/* QR_HPP */
